import { Injectable, HttpException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Article } from "../../entities/article.entity";
import { responseStatus, filterTreeData } from "../../utils";
import * as dayjs from 'dayjs';
import { TagService } from '../tag/tag.service';
import { AuthService } from '../auth/auth.service';
import { CategoryService } from '../category/category.service';
import { newsApi } from '../../api';
@Injectable()
export class ArticleService {
    constructor(@InjectRepository(Article)
    private readonly articleRepository: Repository<Article>,
        private readonly authService: AuthService,
        private readonly categoryService: CategoryService,
        private readonly tagService: TagService
    ) { }
    async get(data) {
        data.current = data.current || 1
        data.pageSize = data.pageSize || 10
        // 1. 准备工作：注入Repository，创建queryBuilder
        // 条件筛选和分页查询代码
        let queryBy = this.articleRepository.createQueryBuilder('article')
            .leftJoinAndSelect('article.comment', 'comment')
            // .andWhere('comment.status = :status', { status: 1001 })
            .leftJoinAndSelect('article.category', 'category')
            .andWhere('article.isDelete=:delete').setParameter('delete', false)

        // 2. 条件筛选查询，如名称、类型等，传入对应字段即可
        // queryBy = queryBy.where(data as Partial<Article>)
        const { current = 1, pageSize = 12, status, order, category, tag, ...otherParams } = data;
        if (status) {
            queryBy.andWhere('article.status=:status').setParameter('status', status);
        }
        if (category) {
            const categoryIds = category.split(',');
            queryBy.andWhere('article.categoryId=:category').setParameter('category', categoryIds[categoryIds.length - 1]);
        }
        if (tag) {
            const tagId = ('' + tag).split(',');
            queryBy.leftJoinAndSelect('article.tags', 'tag').andWhere('tag.id in(:id)', { id: tagId })
        } else {
            queryBy.leftJoinAndSelect('article.tags', 'tag')
        }
        // 普通排序
        queryBy = queryBy.orderBy('article.updateTime', 'DESC')
        // .addOrderBy('article.create_time', 'DESC')
        if (order) {
            queryBy = queryBy.orderBy('article.createTime', order || 'DESC')
        }
        if (otherParams) {
          ['title'].forEach(key => {
            otherParams[key] && queryBy
              .andWhere(`article.${key} LIKE :${key}`)
              .setParameter(`${key}`, `%${otherParams[key]}%`);
          });
        }
        // 3. 时间范围筛选
        if (data && data['publishTimeStart'] && data['publishTimeEnd']) {
            queryBy = queryBy.andWhere('article.updateTime BETWEEN :start AND :end', {
                start: data['publishTimeStart'],
                end: data['publishTimeEnd']
            })
        }
        if (data && data['createTimeStart'] && data['createTimeEnd']) {
          queryBy = queryBy.andWhere('article.createTime BETWEEN :start AND :end', {
              start: data['createTimeStart'],
              end: data['createTimeEnd']
          })
      }

        // 分页
        queryBy = queryBy
            .skip(pageSize * (current - 1))
            .take(pageSize)
        // 获取结果及(非分页的)查询结果总数
        // 或使用 .getMany() 不会返回总数
        if (data.category || data.tag) {
            return await queryBy.getManyAndCount()
        }
        const res = await queryBy.getManyAndCount()
        // if (current > 1) {
        //     return Promise.resolve(res)
        // }
        // res[0] = [...newsList, ...res[0]]
        // console.log(res[0], 'newsRes')
        // return await queryBy.getManyAndCount()
        return Promise.resolve(res)
    }
    async getNews (data = {}) {
        /**
         * 合并第三方新闻接口与博客接口一同返回
         * 对接第三方sdk api
         */
        let newsList = []
        let listRes = { data: [], code: 200 }
        // listRes = await newsApi.GetById(data)
        listRes = await newsApi.toutiao(data)
        newsList = listRes.data && listRes.data.map(el => ({
            content: el.has_video ? el.large_image_url : el.abstract,
            title: el.title,
            createTime: new Date(new Date(el.datetime).getTime() - el.publish_time),
            updateTime: new Date(new Date(el.datetime).getTime() - el.behot_time),
            comment: [],
            tags: [],
            mediaName: el.media_name,
            source: el.source,
            commentCount: el.comment_count,
            img: el.image_list[0] && el.has_image ? el.image_list[0].url : '',
            imageList: el.has_image ? el.image_list : [],
            url: el.display_url || el.share_url,
            status: 1001,
            category: {
               createTime: new Date(new Date(el.datetime).getTime() - el.publish_time),
               id: el.item_id,
               label: null,
               parentId: null,
               status: 1001,
               updateTime: new Date(new Date(el.datetime).getTime() - el.behot_time),
               value: el.tag
           }
        }))
        // console.log(newsList, 'newsList');
        newsList.map(el => {
            this.create(el)
        })
        return newsList || []
    }

    async getNewsById(data = {}) {
        /**
         * 合并第三方新闻接口与博客接口一同返回
         * 对接第三方sdk api
         */
        let listRes = { Data: { data: [] }, code: 200 }
        listRes = await newsApi.GetById(data)
        return listRes.Data ?.data || []
    }

    async getNewsCate() {
        /**
         * 合并第三方新闻接口与博客接口一同返回
         * 对接第三方sdk api
         */
        let listRes = { Data: { data: [] }, code: 200 }
        listRes = await newsApi.GetAllType()
        // console.log(listRes, 'asdada')
        return listRes.Data || []
    }
    /**
     * 获取新闻关键词
     */
    async getKeyWord () {
        const keyWordRes = await newsApi.hotNews({})
        if (keyWordRes && keyWordRes.code === 200) {
            keyWordRes.newslist = keyWordRes.newslist.map(el => el.Title).slice(0, 10)
            return Promise.resolve([...keyWordRes.newslist])
        } else {
            throw new HttpException(keyWordRes.msg, responseStatus.failed.code);
        }
    }
    /**
     * 获取所以文章
     */
    async getAll(data) {
        let queryBy = this.articleRepository.createQueryBuilder('article')
        const { order } = data
        queryBy = queryBy.leftJoinAndSelect('article.comment', 'comment')
        .andWhere('article.isDelete=:delete').setParameter('delete', 0)
            // .andWhere('comment.status = :status', { status: 1001 })
            .orderBy('article.updateTime', 'DESC')
        if (order) {
            queryBy = queryBy
            .orderBy('article.createTime', order || 'DESC')
        }
        // let newsList = []
        // const listRes = await newsApi.hotNews({})
        // if (listRes.Code === 200) {
        //     newsList = listRes.Data
        //     newsList.map(el => {
        //             el.content = el.Desc
        //             el.createTime = new Date(el.CreateTime)
        //             el.updateTime = new Date(el.CreateTime)
        //             el.comment = []
        //             el.img = el.picUrl
        //             el.url = el.Url
        //             el.title = el.Title
        //             el.status = 1001
        //             el.category = {
        //                 createTime: new Date(el.CreateTime),
        //                 id: el.uniquekey,
        //                 label: null,
        //                 parentId: null,
        //                 status: 1001,
        //                 updateTime: new Date(el.CreateTime),
        //                 value: el.category
        //             }
        //     })
        // }
        // // 获取结果及(非分页的)查询结果总数
        // // 或使用 .getMany() 不会返回总数
        // newsList = newsList.slice(0,2)
        queryBy = queryBy
            .skip(10 * (1 - 1))
            .take(10)
        const res = await queryBy.getManyAndCount()
        // res[0] = res[0].slice(0, 2)
        // res[0] = newsList.concat(res[0])
        // res[1] += newsList.length
        // console.log(res, 'keyWordRes')
        return Promise.resolve(res)
        // return await queryBy.getManyAndCount()
    }
    /**
     * 创建文章 create(data: Partial<Article>): Promise<Article>
     * @param data
     */
    async create(data): Promise<any> {
        // article.id = this.articles.length + 1
        // this.articles.push(article)
        // return Promise.resolve('操作成功');
        const { title } = data;
        const exist = await this.articleRepository.findOne({ where: { title } });

        if (exist) {
            // process.on('unhandledRejection', error => {
            //     console.error('文章标题已存在', error);
            //     process.exit(1) // To exit with a 'failure' code
            // })
            return new HttpException('文章标题已存在', responseStatus.failed.code);
            // return Promise.reject(responseStatus.failed)
        }
        let { tags = [], categoryId = null } = data
        if (data.status === '1001') {
            Object.assign(data, {
                updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
            });
        }
        tags = await this.tagService.findByIds(('' + tags).split(','))
        if (categoryId) {
            const categoryIds = categoryId.split(',');
            const lastId = categoryIds[categoryIds.length - 1];
            categoryId = await this.categoryService.getById(lastId);
        }
        const newArticle = await this.articleRepository.create({
            ...data,
            category: categoryId,
            tags
        });
        return await this.articleRepository.save(newArticle);
    }
    /**
     *  更新指定文章
     * @param data
     */
    async edit(data): Promise<Article> {
        const oldArticle = await this.articleRepository.findOne({ id: data.id });
        if (!oldArticle) {
            // throw new HttpException('查询文章不存在！', responseStatus.failed.code);
            this.create(data)
        }
        let { tags, categoryId } = data;

        if (tags) {
            tags = await this.tagService.findByIds(('' + tags).split(','));
        }
        if (categoryId && categoryId !== null) {
            const categoryIds = categoryId.split(',');
            const lastId = categoryIds[categoryIds.length - 1];
            categoryId = await this.categoryService.getById(lastId);
        }
        const newArticle = {
            ...data,
            updateTime:
                oldArticle.status === '1001'
                    ? dayjs().format('YYYY-MM-DD HH:mm:ss')
                    : oldArticle.updateTime,
        };

        if (tags) {
            Object.assign(newArticle, { tags });
        } else {
            Object.assign(newArticle, { tags: [] });
        }
        if (categoryId) {
            Object.assign(newArticle, { category: categoryId });
        } else {
            Object.assign(newArticle, { category: null });
        }
        const { id, ...otherParams } = newArticle
        // const updatedArticle = await this.articleRepository.merge(
        //     oldArticle,
        //     newArticle
        // );
        const updatedArticle = { ...oldArticle, ...otherParams }
        return this.articleRepository.save(updatedArticle);
    }
    /**
     * 根据id删除文章
     * @param id 
     */
    async delete(id) {
        // console.log(id, 'iddddddd')
        const res = await this.articleRepository.findOne({ id: +id })
        if (res) {
            await this.articleRepository.save({ ...res, isDelete: true })
            return responseStatus.success.message
        }
        else throw new HttpException(`暂无数据`, 404);
    }
    // 批量删除文章
    async batchDelete({ ids }) {
        // return Promise.resolve('操作成功！');
        if (!ids) {
            throw new HttpException("参数为空", responseStatus.failed.code);
        }
        ids = ids.split(',')
        const hasArticle = await this.articleRepository.findByIds(ids)
        // console.log(hasArticle)
        if (!hasArticle) {
            throw new HttpException("评论不存在！", responseStatus.failed.code);
        } else {
            await this.articleRepository.remove(hasArticle)
            return responseStatus.success.message
        }
    }
    /**
     * 根据id获取文章
     * @param id 文章id
     */
    async getById(id: number) {
        // const article = this.articles.find(article => article.id === id)
        // return Promise.resolve(article);
        const res = await this.articleRepository.findOne({ id }, { relations: ['comment'] })
        if (!res) throw new HttpException(`暂无数据`, 404);

        // 新增访客量
        const updatedArticle = { ...res, visitor: (+res.visitor) + 1 }
        await this.articleRepository.save(updatedArticle);

        let queryBy = this.articleRepository.createQueryBuilder('article')
            .leftJoinAndSelect('article.tags', 'tag')
            .leftJoinAndSelect("article.comment", "comment")
            .leftJoinAndSelect('article.category', 'category')
            .orderBy('comment.create_time', 'DESC')
        // queryBy.leftJoinAndSelect('article.category', 'category')
        //     .orderBy('category.create_time', 'DESC')
        queryBy = queryBy.andWhere(`article.id=${id}`)
        // console.log(await queryBy.getOne(), 'queryBy.getOne()')
        const data = await queryBy.getOne()
        data.comment = filterTreeData(data.comment, null)
        const resData = { ...data, categoryId: '' }
        const categoryId = []
        if (data.category !== null) {
            categoryId.push(data.category.id)
            if (data.category.parentId !== null) {
                categoryId.unshift(data.category.parentId)
                const category = await this.categoryService.getById(data.category.parentId);
                if (category.parentId !== null) {
                    categoryId.unshift(category.parentId)
                }
            }
            resData.categoryId = categoryId.join(',')
        }
        return Promise.resolve(resData)
    }
    // 设置文章状态
    async setStatus({ id, status }) {
        if (!id || !status) {
            throw new HttpException("参数为空", responseStatus.failed.code);
        }
        const existData = await this.articleRepository.findOne({ id })
        if (!existData) {
            throw new HttpException("文章不存在！", responseStatus.failed.code);
        }
        const updatedArticle = { ...existData, status, updateTime: status === 
          1002 ? existData.updateTime : dayjs().format('YYYY-MM-DD HH:mm:ss') }
        await this.articleRepository.save(updatedArticle)
        return responseStatus.success.message
    }
    // 批量修改状态
    async batchStatus({ ids, status }) {
        if (!ids || !status) {
            throw new HttpException("参数为空", responseStatus.failed.code);
        }
        ids = ids.split(',')
        const existComment = await this.articleRepository.findByIds(ids)
        // console.log(existComment)
        if (!existComment) {
            throw new HttpException("评论不存在！", responseStatus.failed.code);
        }
        const updatedArticle = []
        existComment.map(el => {
            updatedArticle.push({...el, status: status, updateTime: status === 
              1002 ? el.updateTime : dayjs().format('YYYY-MM-DD HH:mm:ss')})
        })
        await this.articleRepository.save(updatedArticle)
        return responseStatus.success.message
    }
}
